// 并发读取文件目录
package main

import (
	"context"
	"flag"
	"fmt"
	"githun.com/olivere/elastic"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"sync"
	"time"
)

var whiteList sync.Map
var wg sync.WaitGroup
var sema = make(chan struct{}, 20) // 计数令牌，保证打开的文件数不过多

type fileInfo struct {
	Name string `json:"name"`
	Path string `json:"path"`
	Dir  string `json:"dir"`
	Size int64  `json:"size"`
}

func main() {
	go func() {
		http.ListenAndServe(":8081", nil)
	}()
	flag.Parse()
	roots := flag.Args()
	if len(roots) == 0 {
		roots = []string{"."}
	}
	whiteList.Store("node_modules", struct{}{})
	start := time.Now()
	wg.Add(1)
	go walkDir(roots[0])
	wg.Wait()
	duration := time.Now().Sub(start).Seconds()
	fmt.Println(duration)
}
func walkDir(dir string) {
	defer wg.Done()
	for _, entry := range directs(dir) {
		if entry.IsDir() {
			if _, exists := whiteList.Load(entry.Name()); exists {
				continue
			}
			subdir := filepath.Join(dir, entry.Name())
			wg.Add(1)
			go walkDir(subdir)
		} else {
			data := fileInfo{
				Name: entry.Name(),
				Path: filepath.Join(dir, entry.Name()),
				Dir:  dir,
				Size: entry.Size(),
			}
			wg.Add(1)
			go func() {
				defer wg.Done()
				log.Println(data)
			}()
		}
	}
}

func directs(dir string) []os.FileInfo {
	sema <- struct{}{}
	defer func() { <-sema }()
	entires, err := ioutil.ReadDir(dir)
	if err != nil {
		log.Printf("read err : dir: %s, err: %s \n", dir, err)
		return nil
	}
	return entires
}

func save2es() {
	es, _ := elastic.NewClient()
	es.Index().Id("aa").BodyJson(fileInfo{}).Do(context.Background())

}
